﻿#include "user.h"
#if PRINTF_LOG
#include "../inc/virtual_uart.h"

int virtual_uart_tx_buff_write(virtual_uart_t *virtual_uart_handler, uint8_t dat)
{
	if (virtual_uart_handler->virtual_tx_buff.len >= TX_BUFF_SIZE)
	{
		return -1;
	}
	
	/*等待 模拟串口发送完成*/
	while(virtual_uart_handler->tx_transaction.send_cnt != 0)
	;

	virtual_uart_handler->ENTER_CRITICAL(); // 进入临界区
	virtual_uart_handler->virtual_tx_buff.tx_buff[virtual_uart_handler->virtual_tx_buff.tail] = dat;
	virtual_uart_handler->virtual_tx_buff.tail = (virtual_uart_handler->virtual_tx_buff.tail + 1) % TX_BUFF_SIZE;
	virtual_uart_handler->virtual_tx_buff.len++;
#if VIRTUAL_TX_SLEEP
	if (virtual_uart_handler->is_sleep == true) // 如果查询到定时器已休眠，那么本次需要对其进行重启
	{
		virtual_uart_handler->is_sleep = false;		  // 还原定时器休眠标志
		virtual_uart_handler->virtual_uart_restart(); // 重启定时器并开启中断
	}
	else // 不然正常的退出临界区即可
	{
		virtual_uart_handler->EXIT_CRITICAL(); // 离开临界区
	}
#else
	virtual_uart_handler->EXIT_CRITICAL();     // 离开临界区
#endif
	return 0;
}
/**
 * @brief 环形队列读取缓冲区
 *
 * @param virtual_uart_handler 模拟串口句柄
 *
 * @return int
 * @retval  0 ： 队列为空
 * @retval  1 ： 内容读取成功，需要执行发送
 */
static int virtual_uart_tx_buff_read(virtual_uart_t *virtual_uart_handler)
{
	if (virtual_uart_handler->virtual_tx_buff.len == 0) // 队列是否为空
	{
		return 0;
	}

	virtual_uart_handler->tx_transaction.send_temp = virtual_uart_handler->virtual_tx_buff.tx_buff[virtual_uart_handler->virtual_tx_buff.head];
	virtual_uart_handler->virtual_tx_buff.head = (virtual_uart_handler->virtual_tx_buff.head + 1) % TX_BUFF_SIZE;
	virtual_uart_handler->virtual_tx_buff.len--;
	return 1;
}
/**
 * @brief 计算字节内1的个数
 *
 * @param dat 需要计算的数据
 *
 * @return int 1的个数
 */
static uint8_t get_parity_cnt(uint8_t dat)
{
	int ret = 0;
	for (int i = 0; i < 8; i++)
	{
		if (dat & (1 << i))
		{
			ret++;
		}
	}
	return ret;
}
#include "main.h"


void virtual_uart_loop(virtual_uart_t *virtual_uart_handler)
{
	switch (virtual_uart_handler->tx_transaction.send_cnt)
	{
	case 0: //判断是否有数据  
	{
		if (virtual_uart_tx_buff_read(virtual_uart_handler)) // 查询到有内容需要被发送
		{
			// virtual_uart_handler->reset_io();
			virtual_uart_handler->tx_transaction.send_cnt++;
		}
		else
		{
			virtual_uart_handler->set_io();
#if VIRTUAL_TX_SLEEP
			virtual_uart_handler->is_sleep = true;
			virtual_uart_handler->virtual_uart_sleep();
#endif
		}
	}
	break;
	case 1: // 起始位拉低
	{
			virtual_uart_handler->reset_io();
			virtual_uart_handler->tx_transaction.send_cnt++;
	}
	break;
	case 10: // 是否需要校验位
	{
		switch (virtual_uart_handler->virtual_uart_config.PARITY)
		{
		case VIRTUAL_UART_PARITY_DISABLE: // 无校验，直接发送停止位
		{
			virtual_uart_handler->set_io();
			virtual_uart_handler->tx_transaction.send_cnt = 0;
		}
		break;
		case VIRTUAL_UART_PARITY_EVEN: // 偶校验
		{
			int cnt = get_parity_cnt(virtual_uart_handler->tx_transaction.send_temp);
			/*如果 8 位数据位中 1 的个数为偶数，该位设为 0（置低电平），否则为 1（置高电平）*/
			if ((cnt % 2) == 0)
			{
				virtual_uart_handler->reset_io();
			}
			else
			{
				virtual_uart_handler->set_io();
			}
			virtual_uart_handler->tx_transaction.send_cnt++;
		}
		break;
		case VIRTUAL_UART_PARITY_ODD: // 奇校验
		{
			int cnt = get_parity_cnt(virtual_uart_handler->tx_transaction.send_temp);
			/*如果 8 位数据位中 1 的个数为奇数，该位设为 0（置低电平），否则为 1（置高电平）*/
			if (cnt % 2)
			{
				virtual_uart_handler->reset_io();
			}
			else
			{
				virtual_uart_handler->set_io();
			}
			virtual_uart_handler->tx_transaction.send_cnt++;
		}
		break;

		default:
			break;
		}
	}
	break;
	case 11: // 结束位拉高
	{
		virtual_uart_handler->set_io();
		virtual_uart_handler->tx_transaction.send_cnt = 0;
	}
	break;

	default:
	{
		if (virtual_uart_handler->tx_transaction.send_temp & (1 << (virtual_uart_handler->tx_transaction.send_cnt - 2)))
		{
			virtual_uart_handler->set_io();
		}
		else
		{
			virtual_uart_handler->reset_io();
		}
		virtual_uart_handler->tx_transaction.send_cnt++;
	}
	break;
	}
}
#endif
